package com.sunyy.wordparser.parser;

import com.sunyy.wordparser.pojo.entity.CmdEntity;
import com.sunyy.wordparser.pojo.entity.ParamEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author : zhangxin
 * @date : 2024/9/13 下午3:23
 **/
@Slf4j
public class WordParser1 {

    private static final Pattern pattern = Pattern.compile("[<\\[]HUAWEI.*?[>\\]]\\s[A-Za-z].*");

    public static void main(String[] args) throws IOException {
        process36331();
    }


    public static void process36331() throws IOException {
        String filePath = "D:\\Documents\\Test\\S9300, S9300X 产品文档\\S9300, S9300X 产品文档_20241118 141956.docx";
        String outPath = "D:\\Documents\\Test\\output";

        try (InputStream file = Files.newInputStream(Paths.get(filePath));
             XWPFDocument document = new XWPFDocument(file)) {
            List<CmdEntity> cmdEntities = parseDocument(document);
            log.info("解析结果：{}", cmdEntities.size());
            buildExcel(cmdEntities,outPath);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 根据需求输出excel
     *
     * @param cmdEntities 命令实体集合
     */
    private static void buildExcel(List<CmdEntity> cmdEntities,String path) {

        String[] title = new String[]{"命令名称", "命令", "命令功能", "命令格式", "参数", "参数说明", "取值", "视图", "缺省级别", "使用指南", "使用实例"};
        String[] title2 = new String[]{"命令名称", "使用实例指令"};
        Path outputPath = Paths.get(path, "20241118 141956.xlsx");
        try {
            Files.deleteIfExists(outputPath);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        int rowNum = 0;
        int rowSheet2Num = 0;
        try (Workbook workbook = new XSSFWorkbook();
             OutputStream os = Files.newOutputStream(outputPath)) {
            Sheet sheet = workbook.createSheet();
            Sheet sheet2 = workbook.createSheet();
            Row row = sheet.createRow(rowNum++);
            for (int i = 0; i < title.length; i++) {
                Cell cell = row.createCell(i);
                cell.setCellValue(title[i]);
            }
            Row rowSheet2 = sheet2.createRow(rowSheet2Num++);
            for (int i = 0; i < title2.length; i++) {
                Cell cell = rowSheet2.createCell(i);
                cell.setCellValue(title2[i]);
            }
            for (CmdEntity cmdEntity : cmdEntities) {
                getHuaWeiDetail(cmdEntity, sheet2, rowSheet2Num);
                rowSheet2Num += cmdEntity.getHuaweiCmd().size();
                if (cmdEntity.getParams().isEmpty()) {
                    ParamEntity paramEntity = new ParamEntity();
                    paramEntity.setParamName("");
                    paramEntity.setParamDesc("");
                    paramEntity.setValueDesc("");
                    cmdEntity.getParams().add(paramEntity);
                }
                if (cmdEntity.getCmdFormat().isEmpty()) {
                    cmdEntity.getCmdFormat().add("");
                }
                for (int i = 0; i < cmdEntity.getCmdFormat().size(); i++) {
                    String cmdFormat = cmdEntity.getCmdFormat().get(i);
                    String cmd;
                    String cmdPower;
                    if (cmdEntity.getCmdPower().isEmpty()) {
                        cmd = "";
                        cmdPower = "";
                    } else {
                        int idx = i % cmdEntity.getCmdPower().size();
                        cmd = cmdEntity.getCmd().get(idx);
                        cmdPower = cmdEntity.getCmdPower().get(idx);
                    }
                    for (ParamEntity param : cmdEntity.getParams()) {
                        row = sheet.createRow(rowNum++);
                        for (int j = 0; j < title.length; j++) {
                            row.createCell(j);
                        }
                        row.getCell(0).setCellValue(cmdEntity.getCmdName());
                        row.getCell(1).setCellValue(cmd);
                        row.getCell(2).setCellValue(cmdPower);
                        row.getCell(3).setCellValue(cmdFormat);
                        row.getCell(4).setCellValue(param.getParamName());
                        row.getCell(5).setCellValue(param.getParamDesc());
                        row.getCell(6).setCellValue(param.getValueDesc());
                        row.getCell(7).setCellValue(cmdEntity.getView().toString());
                        row.getCell(8).setCellValue(cmdEntity.getDefaultLevel().toString());
                        row.getCell(9).setCellValue(cmdEntity.getUsageGuide().toString());
                        row.getCell(10).setCellValue(cmdEntity.getExample().toString());
                    }
                }
            }
            workbook.write(os);
            os.flush();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        log.info("文件输出位置: {}", outputPath);
    }

    /**
     * 可以按照标题类型来解析，
     * 但是我的文档标题类型全文一致，
     * 因此只能用特殊的字和字体大小来解析
     *
     * @param document 文档对象
     */
    private static List<CmdEntity> parseDocument(XWPFDocument document) {
        List<CmdEntity> data = new ArrayList<>();
        final Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+\\s([^\\u4e00-\\u9fa5]+)");
        int curr = -1;
        CmdEntity cmdEntity = null;

        List<IBodyElement> bodyElements = document.getBodyElements();
        for (int x = 0; x < bodyElements.size(); x++) {
            IBodyElement iBodyElement = bodyElements.get(x);
            if (iBodyElement instanceof XWPFParagraph paragraph) {
                String paragraphText = paragraph.getText();
                List<XWPFRun> runs = paragraph.getRuns();
                if (runs.isEmpty()) {
                    continue;
                }
                if ("18.0".equals(String.valueOf(runs.get(0).getFontSizeAsDouble()))) {
                    Matcher matcher = pattern.matcher(paragraphText);
                    if (!matcher.matches()) {
                        cmdEntity = null;
                        log.info("小二字体 不饿能识别的 cmd {}", paragraphText);
                        continue;
                    }
                    String cmdName = matcher.group(1);
                    if (StringUtils.isBlank(cmdName)) {
                        cmdEntity = null;
                        log.error("正则匹配失败");
                        continue;
                    }
                    cmdEntity = CmdEntity.buildCmdEntity();
                    curr = -1;
                    cmdEntity.setCmdName(cmdName);
                    data.add(cmdEntity);
                } else if ("15.0".equals(String.valueOf(runs.get(0).getFontSizeAsDouble()))) {
                    if (cmdEntity == null) {
                        continue;
                    }
                    if ("命令功能".equals(paragraphText)) {
                        curr = 0;
                    } else if ("命令格式".equals(paragraphText)) {
                        curr = 1;
                    } else if ("参数说明".equals(paragraphText)) {
                        curr = 2;
                    } else if ("视图".equals(paragraphText)) {
                        curr = 3;
                    } else if ("缺省级别".equals(paragraphText)) {
                        curr = 4;
                    } else if ("使用指南".equals(paragraphText)) {
                        curr = 5;
                    } else if ("使用实例".equals(paragraphText)) {
                        curr = 6;
                    } else {
                        log.error("未定义的段落：{}", paragraphText);
                    }
                } else {
                    if (cmdEntity == null) {
                        continue;
                    }
                    if (curr == 0) {
                        int i = paragraphText.indexOf(cmdEntity.getCmdName());
                        if (i == -1) {
                            continue;
                        }
                        String trim = paragraphText.substring(0, i + cmdEntity.getCmdName().length()).trim();
//                        if (StringUtils.isBlank(trim)) {
//                            continue;
//                        }
                        cmdEntity.getCmd().add(trim);
                        cmdEntity.getCmdPower().add(paragraphText);
                    } else if (curr == 1) {
                        cmdEntity.getCmdFormat().add(paragraphText);
                    } else if (curr == 3) {
                        cmdEntity.getView().append(paragraphText);
                    } else if (curr == 4) {
                        cmdEntity.getDefaultLevel().append(paragraphText);
                    } else if (curr == 5) {
                        cmdEntity.getUsageGuide().append(paragraphText);
                    } else if (curr == 6) {
                        cmdEntity.getExample().append(paragraphText).append("\n");
                    } else {
                        log.error("不能识别的标志 curr = {}", curr);
                    }
                }

            } else if (iBodyElement instanceof XWPFTable table) {
                if (curr != 2 || cmdEntity == null) {
                    log.info("未定义的表格");
                    continue;
                }
                // 校验表格
                List<XWPFTableRow> rows = table.getRows();
                if (rows.size() <= 1) {
                    continue;
                }
                XWPFTableRow header = rows.get(0);
                if (header.getTableCells().size() != 3
                        || !"参数".equals(header.getCell(0).getText())
                        || !"参数说明".equals(header.getCell(1).getText())
                        || !"取值".equals(header.getCell(2).getText())) {
                    log.info("参数表格格式错误");
                    continue;
                }
                for (int i = 1; i < rows.size(); i++) {
                    XWPFTableRow xwpfTableRow = rows.get(i);
                    ParamEntity paramEntity = new ParamEntity();
                    paramEntity.setParamName(xwpfTableRow.getCell(0).getText());
                    paramEntity.setParamDesc(xwpfTableRow.getCell(1).getText());
                    paramEntity.setValueDesc(xwpfTableRow.getCell(2).getText());
                    cmdEntity.getParams().add(paramEntity);
                }
            }
        }
        return data;
    }

    private static void getHuaWeiDetail(CmdEntity cmdEntity, Sheet rowSheet2, int rowSheet2Num) {
        Matcher matcher = pattern.matcher(cmdEntity.getExample());
        while (matcher.find()) {
            String group = matcher.group();
            if (group.contains("\n") || group.contains("\r") || group.contains("\n\r") || group.contains("\r\n")) {
                continue;
            }
            cmdEntity.getHuaweiCmd().add(group);
            Row row = rowSheet2.createRow(rowSheet2Num++);
            row.createCell(0).setCellValue(cmdEntity.getCmdName());
            row.createCell(1).setCellValue(group);
        }
    }
}
